class SocketPannel extends egret.Sprite {
    private socket:egret.WebSocket;

    private w:number=0;
    private h:number=0;
    private scale:number=1;

    private space: egret.Shape;
    private blockContainer: egret.Sprite;
    private personContainer: egret.Sprite;

    private players: Array<any>;
    private bullets: Array<any>;
    private damages: Array<any>;

    private blockInitialization = 0;
    private blocks:  Array<any>;

    private defaultScreen = {"w": 0, "h": 0};

    // public static serverHost = "tank.haowanh5.com"; // Online Dev Server
    // public static serverHost: string = "192.168.0.116"; // Inhouse Dev Server
    public static serverHost: string = "127.0.0.1"; // Personal PC
    public static serverPort: number = 15000;

	public constructor() {
        super();
        this.initSocket();
	}

    private initSocket(): void{
        this.players = [];
        
        this.socket=new egret.WebSocket();
        // this.socket.type = egret.WebSocket.TYPE_BINARY;
        this.socket.addEventListener(egret.ProgressEvent.SOCKET_DATA, this.onReceiveMessage, this);
        this.socket.addEventListener(egret.Event.CONNECT, this.onSocketOpen, this);
        this.socket.connect(SocketPannel.serverHost, SocketPannel.serverPort);

        // Init Background With Eye Protect Color
        this.space = new egret.Shape();
        this.space.graphics.beginFill(0xC7EDCC);
        this.space.graphics.drawRect(0, 0, window.innerWidth, window.innerHeight);
        this.space.graphics.endFill();
        this.addChild(this.space);

        this.blockContainer = new egret.Sprite();
        this.addChild(this.blockContainer);

        this.personContainer = new egret.Sprite();
        this.addChild(this.personContainer);
    }

    private sendPacket(packetId, data): void {
        if (!data) data = {};
        data.packetId = packetId;
        this.socket.writeUTF(JSON.stringify(data));
    }

    private onSocketOpen(): void {
        // console.log("Connect To Server [ %s:%s ]", SocketPannel.serverHost, SocketPannel.serverPort);

        this.sendPacket(StaticFile.API.ON_SET_OBSERVE_MODE, {});
    }

    private onReceiveMessage(e:egret.Event): void { 
        var msg: string = this.socket.readUTF();
        var data: JSON  = JSON.parse(msg);
        
        console.log("Read Data From Server", msg);
        
        switch(data["packetId"]) {
            case StaticFile.API.TO_GAME_TIME_OVER:
            // Time Over
            alert("Time Over! Press F5 Refresh!");
            break;
            case StaticFile.API.TO_UPDATE_POSITION:
            // Update Observer Map
                this.updateMap(data);
            break;
        }
    }

    private updateMap(data: JSON): void {
        if (this.w <= 0) {
            this.h = data["mapInfo"]["height"];
            this.w = data["mapInfo"]["width"];
            this.stage.setContentSize(this.w, this.h);
            this.defaultScreen.w = data["screen"]["width"];
            this.defaultScreen.h = data["screen"]["height"];
            this.scale = Math.min(window.innerWidth / this.w, window.innerHeight / this.h);
        }

        this.players = data["allPlayer"] || [];
        // console.log("Players: ", this.players);

        this.bullets = data["allBullet"] || [];
        // console.log("Bullets: ", this.bullets);

        this.damages = data["allDamage"] || [];
        // console.log("Damages: ", this.damages);

        this.blocks  = data["allBlock"] || [];
        // console.log("Blocks: ", this.blocks);

        if (this.blockInitialization % 50 === 0) {
            this.drawBlock();
        }
        this.blockInitialization += 1;
        

        console.log("Players " + this.players.length + " Bullets " + this.bullets.length + " Damage " + this.damages.length + " Block " + this.blocks.length);

        this.drawPerson();
    }

    private drawBlock(): void {
        this.blockContainer.removeChildren();

        // Draw Background - Movable Range
        let moveRange = new egret.Shape();
        moveRange.graphics.beginFill(0xC3E9C9);
        moveRange.graphics.drawRect(0, 0, this.w * this.scale, this.h * this.scale);
        moveRange.graphics.endFill();
        
        this.blockContainer.addChild(moveRange);

        this.addBlocks();
    }

    private drawPerson():void {
        this.personContainer.removeChildren();
        if (this.players.length < 0) return;

        this.addPlayers();
        this.addBullets();
        this.addDamages();
    }

    private addPlayers(): void {

        for(let i=0; i<this.players.length; i++) {
            let playerData = this.players[i];

            // Set Player Object
            let player:Player = new Player();
            player.scaleX     = this.scale;
            player.scaleY     = this.scale;

            player.w          = playerData["screen"] ? playerData["screen"]["width"] : this.defaultScreen.w;
            player.h          = playerData["screen"] ? playerData["screen"]["height"]: this.defaultScreen.h;
            player.x          = playerData["position"]["x"] * this.scale;
            player.y          = playerData["position"]["y"] * this.scale;

            player.isBot      = playerData["isBot"];
            player.id         = playerData["objectId"];
            player.createPlayer();
            this.personContainer.addChild(player);

            // Set Player Marker
            let label        = new egret.TextField();
            label.fontFamily = "Arial";
            label.textColor  = player.color;
            label.size       = StaticFile.labelSize;
            label.text       = "" + player.id;
            label.width      = StaticFile.tankSize;
            label.height     = StaticFile.tankSize;
            label.x          = player.x - 10;
            label.y          = player.y - 10;
            this.personContainer.addChild(label);
        }

    }

    private addBullets (): void {
        
        for (let j = 0; j < this.bullets.length; j++) {
            let bulletData = this.bullets[j];

            // Only Handle 100 Bullets
            // if (j > 100) break;

            let bullet: Bullet = new Bullet();
            bullet.scaleX     = this.scale;
            bullet.scaleY     = this.scale;

            bullet.x          = bulletData["position"]["x"] * this.scale;
            bullet.y          = bulletData["position"]["y"] * this.scale;

            bullet.id         = bulletData["objectId"];
            bullet.createBullet();
            this.personContainer.addChild(bullet);

            // let label        = new egret.TextField();
            // label.fontFamily = "Arial";
            // label.textColor  = bullet.color;
            // // label.size       = 16 * this.scale;
            // label.size       = StaticFile.labelSize;
            // // label.text       = "" + (bullet.id % 20);
            // label.text       = "" + (bullet.id);
            // label.width      = StaticFile.tankSize;
            // label.height     = StaticFile.tankSize;
            // label.x          = bullet.x - 5;
            // label.y          = bullet.y - 5;
            // this.personContainer.addChild(label);
        }

    }

    private addDamages(): void {
        
        for (let k = 0; k < this.damages.length; k++) {
            let damageData = this.damages[k];

            // Only Handle 100 Bullets
            // if (j > 100) break;

            let damage: Bullet = new Bullet();
            damage.scaleX     = this.scale;
            damage.scaleY     = this.scale;

            damage.x          = damageData["position"]["x"] * this.scale;
            damage.y          = damageData["position"]["y"] * this.scale;

            damage.id         = damageData["objectId"];
            damage.createBullet();
            this.personContainer.addChild(damage);

            let label        = new egret.TextField();
            label.fontFamily = "Arial";
            label.textColor  = damage.color;
            label.size       = StaticFile.labelSize * 2 * this.scale;
            label.text       = "" + (damage.id);
            label.width      = 4 * StaticFile.labelSize;
            label.height     = 4 * StaticFile.labelSize;
            label.x          = damage.x - StaticFile.labelSize / 2;
            label.y          = damage.y - StaticFile.labelSize / 2;
            this.personContainer.addChild(label);
        }

    }

    private addBlocks(): void {

        let block: Block = new Block();
        block.createBlocks(this.blocks, this.scale);
        this.blockContainer.addChild(block);

        // for(let i=0; i<this.blocks.length; i++) {
        //     let blockData = this.blocks[i];

        //     // Set Block Object
        //     let block:Block = new Block();
        //     block.scaleX     = this.scale;
        //     block.scaleY     = this.scale;

        //     block.w          = blockData["box"]["x"] * this.scale / 2;
        //     block.h          = blockData["box"]["y"] * this.scale / 2;
        //     block.x          = blockData["position"]["x"] * this.scale;
        //     block.y          = blockData["position"]["y"] * this.scale;

        //     block.id         = blockData["objectId"];
        //     block.createBlock();
        //     this.blockContainer.addChild(block);

        //     // Set Block Marker
        //     // let label        = new egret.TextField();
        //     // label.fontFamily = "Arial";
        //     // label.textColor  = block.color + 65535;
        //     // // label.size       = 16 * this.scale;
        //     // label.size       = 16;
        //     // label.text       = "" + block.id;
        //     // label.width      = StaticFile.tankSize;
        //     // label.height     = StaticFile.tankSize;
        //     // label.x          = block.x - 10;
        //     // label.y          = block.y - 10;
        //     // this.blockContainer.addChild(label);
        // }

    }

    private trace(msg: any): void {
        // this.text = this.text + "\n" + msg;
        // this.stateText.text = this.text;
        // egret.log(msg);
        console.log(msg);
    }
	
}
